package com.ray.aopdemo.aopdemo;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;

/**
 * User: Ray.Shaw <p />
 * Time: 2019/11/1 14:32  <p />
 * Version: V1.0  <p />
 * Description: https://www.jianshu.com/p/aaeb2355ec5c <p />
 */
public class TestProxy {
    public static void main(String[] args) {
        new TestProxy().testAop();
    }

    public void testAop() {
        /**
         * 三个参数
         * 1、ClassLoader
         * 方法需要动态生成一个类，这个类实现了A和B两个接口，然后创建这个类的对象
         * 需要生成一个类，这个类也需要加载到方法区中，所以我们需要一个ClassLoader来加载该类
         *
         * 2、Class[] interfaces
         * 我们需要代理对象实现的数组
         *
         * 3、InvocationHandler
         * 调用处理器
         *
         * 代理对象实现的所有接口中的方法，内容都是调用InvocationHandler的invoke()方法
         */
        ClassLoader classLoader = this.getClass().getClassLoader();
        //这里创建一个空实现的调用处理器。
        InvocationHandler invocationHandler = new InvocationHandler() {
            @Override
            public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
                System.out.println("你好---> " + method.toString());//注意这里添加了一点小逻辑
                return "hello-x";
            }
        };
        Object obj = Proxy.newProxyInstance(classLoader, new Class[]{A.class, B.class}, invocationHandler);

        System.out.println("=======================================================================================");
        A a = (A) obj;
        B b = (B) obj;
//        a.a();
//        b.b();

        a.toString();//注意这里调用了toString()方法
//        b.getClass();//注意这里调用了getClass()方法

        System.out.println("obj.getClass(): " + obj.getClass());//这里看一下代理对象是什么

        Object a1 = a.aaa("asshole", 100);
        //这个调用了动态代理的InvocationHandler的invoke方法. 返回值也是invoke方法返回的值。
        System.out.println("a1: " + a1);//这里看一下返回值是什么

        Object a2 = a.aaa1("fuck", 1);
        //这个调用了动态代理的InvocationHandler的invoke方法. 返回值也是invoke方法返回的值。
        System.out.println("a2: " + a2);//这里看一下返回值是什么


    }
}
